using System.Collections.Generic;

namespace Arcane.Source.Utils
{
    public class Registry<K, V>
    {
        private readonly Dictionary<K, int> _keyMap = [];
        private readonly List<V> _entries = [];
        private readonly MinHeap<int> _holes = new();

        public class Identifier
        {
            public K key;
            public int index;
        }

        public Identifier CreateEntry(K key, V value)
        {
            int id;
            if (_holes.Count > 0)
            {
                id = _holes.Pop();
                _entries[id] = value;
            }
            else
            {
                id = _entries.Count;
                _entries.Add(value);
            }

            _keyMap.Add(key, id);

            return new Identifier
            {
                key = key,
                index = id,
            };
        }

        public bool IsIDValid(Identifier id) => ContainsKey(id.key);

        public void Remove(Identifier id)
        {
            _holes.Push(id.index);
            _keyMap.Remove(id.key);
        }

        public V GetEntry(Identifier id) => _entries[id.index];

        public Identifier GetId(K key) => new()
        {
            key = key,
            index = GetIndex(key),
        };

        public int GetIndex(K key) => _keyMap[key];
        private bool ContainsKey(K key) => _keyMap.ContainsKey(key);
    }
}